<?php

namespace app\api\model\xykeep\course;

use think\Db;
use think\Model;
use traits\model\SoftDelete;
use app\api\model\xykeep\User;
use app\api\model\xykeep\course\Order as CourseOrderModel;
use app\api\model\xykeep\Course;
use app\common\model\Benfit;
use app\common\model\UserCard;
use app\common\model\UserCardBenfit;
use app\common\model\BenfitLog;
use addons\xykeep\exception\Exception;
use think\Log;
use think\Queue;

class Order extends Model
{

    use SoftDelete;

    // 表名
    protected $name = 'xykeep_course_order';
    
    // 自动写入时间戳字段
    protected $autoWriteTimestamp = 'integer';

    // 定义时间戳字段名
    protected $createTime = 'createtime';
    protected $updateTime = 'updatetime';
    protected $deleteTime = 'deletetime';

    // 追加属性
    protected $append = [
        'pay_type_text',
        'type_text',
        'paytime_text',
        'status_text',
        'ext_arr'
    ];


    public function getExtArrAttr($value, $data)
    {
        $ext = (isset($data['ext']) && $data['ext']) ? json_decode($data['ext'], true) : [];
        return $ext;
    }

    // 取消订单
    public static function cancelOrder($params)
    {
        $user = User::info();
        extract($params);
        $order = self::where(['user_id'=>$user->id,'id'=>$id,'status'=>0])->find();
        if (!$order) {
            new Exception('订单不存在或已取消');
        }
        $order->status = -1;        // 取消订单
        $order->ext = json_encode($order->setExt($order, ['cancel_time' => time()]));      // 取消时间
        $order->save();

        $params = ['order'=>$order,'type'=>'course'];
        \think\Hook::listen('xykeep_order_back_after', $params);

        return $order;
    }



    /**
     * 计算订单价格
     */
    public static function count_price($nums,$price)
    {
        $price = (String)$price;
        $user = User::info();

        $total_amount = bcmul($price,$nums,2);
        $course_benfit_ids = Benfit::where([
            'course_num' => ['gt',0]
        ])->column('id');

        $self_course_benfit_total = UserCardBenfit::where([
            'user_id' => $user->id,
            'benfit_id' => ['in',$course_benfit_ids]
        ])->sum('nums');

        if($self_course_benfit_total >= $nums){
            $discount = $nums;
            $total_money = '0';
        }else{
            $discount = $self_course_benfit_total;
            $nums = $nums - $self_course_benfit_total;
            $nums = (String)$nums;
            $total_money = bcmul($nums,$price,2);
        }

        return ['total_money'=>$total_money,'total_amount'=>$total_amount,'discount'=>$discount,'max_discount' => $self_course_benfit_total];

    }

    /**
     * 添加订单
     */
    public static function addOrder($params){

        $order = Db::transaction(function () use ($params) {
            extract($params);

            if($buy_num<1){
                new Exception('购买数量最少为1');
            }
            if(!$pay_type){
                new Exception('请选择支付方式！');
            }

            $course = Course::get($course_id);
            if (empty($course)) {
                new Exception('课程不存在！');
            }


            $user = User::info();

            $close_time = 1; //15分钟为支付自动关闭

            $orderData = [];
            $orderData['order_sn'] = xykeepCreateOrderNo();
            $orderData['user_id'] = $user->id;
            $orderData['course_id'] = $course['id'];
            $orderData['name'] = $course['name'];
            $orderData['image'] = $course['image'];
            $orderData['price'] = $course['price'];
            $orderData['buy_num'] = $buy_num;
            $orderData['remark'] = $remark;

            $count = self::count_price($buy_num, $course['price']);
            $total_money = $count['total_money'];

            if($pay_type=='balance'){
                $user_money = User::where(['id'=>$user->id])->value('money');
                if($user_money<$total_money){
                    new Exception('余额不足');
                }
            }
            $orderData['total_amount'] = $count['total_amount'];
            $orderData['total_fee'] = $total_money;
            $orderData['pay_type'] = $pay_type;
            if($count['discount']>0){
                $orderData['ext'] = json_encode([
                    'expired_time' => time() + ($close_time * 60),
                    'benfit_num' => $count['discount'],
                ]);
            }else{
                $orderData['ext'] = json_encode([
                    'expired_time' => time() + ($close_time * 60),
                ]);
            }
            $order = new CourseOrderModel();
            $order->allowField(true)->save($orderData);

            //订单关闭队列
//            Queue::later(($close_time * 60), '\addons\xykeep\job\Order@autoClose', ['order' => $order,'type'=>'course'], 'XYkeep');

            return $order;
        });



        return $order;
    }

    /**
     * 订单支付成功
     *
     * @param [type] $order
     * @param [type] $notify
     * @return void
     */
    public function paySuccess($order, $notify)
    {

        $_time = time();
        $order->status = 1;
        $order->paytime = $_time;
        $order->transaction_id = $notify['transaction_id'];
        $order->payment_json = $notify['payment_json'];
        $order->pay_type = $notify['pay_type'];
        $order->pay_fee = $notify['pay_fee'];
        $order->save();

        //更新课程销量
        $course = Course::where(['id'=>$order['course_id'],'status'=>'normal'])->find();
        $course->setInc('sales',$order['buy_num']);

        $params = ['order'=>$order,'type'=>'course'];
        \think\Hook::listen('xykeep_order_payed_after', $params);


        return $order;
    }


    
    public function getPayTypeList()
    {
        return ['wechat' => __('Wechat'),'balance' => __('Balance'),'offline' => __('Offline')];
    }

    public function getStatusList()
    {
        return ['4'=>__('Status 4'), '3'=>__('Status 3') ,'2' => __('Status 2'), '1' => __('Status 1'), '0' => __('Status 0'), '-1' => __('Status -1'), '-2' => __('Status -2'), '-3' => __('Status -3')];
    }

    public function getCtypeList()
    {
        return ['t' => __('Ctype t'), 'b' => __('Ctype b'), 's' => __('Ctype s'), 'z' => __('Ctype z')];
    }
    public function gettypeTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['type']) ? $data['type'] : '');
        $list = $this->getCtypeList();
        return isset($list[$value]) ? $list[$value] : '';
    }

    public function getPayTypeTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['pay_type']) ? $data['pay_type'] : '');
        $list = $this->getPayTypeList();
        return isset($list[$value]) ? $list[$value] : '';
    }


    public function getPaytimeTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['paytime']) ? $data['paytime'] : '');
        return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
    }


    public function getStatusTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['status']) ? $data['status'] : '');
        $list = $this->getStatusList();
        return isset($list[$value]) ? $list[$value] : '';
    }

    protected function setPaytimeAttr($value)
    {
        return $value === '' ? null : ($value && !is_numeric($value) ? strtotime($value) : $value);
    }

    public function course()
    {
        return $this->belongsTo('app\api\model\xykeep\Course', 'course_id', 'id', [], 'LEFT')->setEagerlyType(1);
    }



    public function setExt($order, $field, $origin = [])
    {
        $newExt = array_merge($origin, $field);

        $orderExt = $order['ext_arr'];

        return array_merge($orderExt, $newExt);
    }

    public function user()
    {
        return $this->belongsTo('app\api\model\xykeep\User', 'user_id', 'id', [], 'LEFT')->setEagerlyType(0);
    }

}